package sections;

import static objects.AdapletConstants.sNewLine;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import objects.IObject;
import objects.Type;

public class TypeSection implements ISection
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -3071280817907385549L;
	private Map<String, Type> fTypeList;

	public TypeSection()
	{
		fTypeList = new LinkedHashMap<String, Type>();
	}

	public Type createNewType(String typeName)
	{
		Type type = new Type(typeName);

		fTypeList.put(typeName, type);

		return type;
	}

	public Type getType(String typeName)
	{
		Type type = fTypeList.get(typeName);

		return type;
	}

	private final String buildHeadComment()
	{
		StringBuffer commentBuf = new StringBuffer(1200);

		commentBuf.append("#");
		commentBuf.append(sNewLine);
		commentBuf.append("################################################################################");
		commentBuf.append(sNewLine);
		commentBuf.append("#");
		commentBuf.append(sNewLine);
		commentBuf.append("# Mapping of physical Matrix Types to foreign data tables.  The following");
		commentBuf.append(sNewLine);
		commentBuf.append("# keywords are avalable:");
		commentBuf.append(sNewLine);
		commentBuf.append("#");
		commentBuf.append(sNewLine);
		commentBuf.append("#   id TABLE(COLUMN)[mapped]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   type TABLE(COLUMN) [using TABLE(COLUMN)] [alias name]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   name TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   policy TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   owner TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   default policy name");
		commentBuf.append(sNewLine);
		commentBuf.append("#   default owner name");
		commentBuf.append(sNewLine);
		commentBuf.append("#   default vault name");
		commentBuf.append(sNewLine);
		commentBuf.append("#   vault TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   revision TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   nextrev TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   prevrev TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   description TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   icon TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   locker TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   created TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   modified TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   state TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#   attribute name TABLE(COLUMN) [using TABLE(COLUMN)]");
		commentBuf.append(sNewLine);
		commentBuf.append("#");
		commentBuf.append(sNewLine);
		commentBuf.append("################################################################################");
		commentBuf.append(sNewLine);
		commentBuf.append("#");

		return commentBuf.toString();
	}

	public String buildTypeSectionDefinition()
	{
		StringBuffer typeSectionDef = new StringBuffer(fTypeList.size() * 1000 + 1200);

		typeSectionDef.append(buildHeadComment());
		typeSectionDef.append(sNewLine);

		for (String typeName : fTypeList.keySet())
		{
			Type type = fTypeList.get(typeName);

			typeSectionDef.append(sNewLine);
			typeSectionDef.append(type.toString());
			typeSectionDef.append(sNewLine);
		}

		return typeSectionDef.toString();
	}

	@Override
	public String toString()
	{
		return buildTypeSectionDefinition();
	}

	@Override
	public int getCount()
	{
		return fTypeList.size();
	}

	@Override
	public Section getSectionType()
	{
		return Section.TYPE;
	}

	@Override
	public IObject[] getObjects()
	{
		return fTypeList.values().toArray(new Type[0]);
	}
	
	private void validateState()
	{
		// TODO Auto-generated method stub
		
	}

	private void readObject(ObjectInputStream iStream) throws IOException, ClassNotFoundException
	{
		iStream.defaultReadObject();
		validateState();
	}
	
	private void writeObject(ObjectOutputStream oStream) throws IOException
	{
		oStream.defaultWriteObject();
	}
}
